package cn.minhx.dtm.starter.config;

import cn.minhx.dtm.starter.core.aspect.DistributedTransactionAspect;
import cn.minhx.dtm.starter.core.service.TransactionService;
import cn.minhx.dtm.starter.core.task.TransactionRetryTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * 分布式事务配置类 只有当dtm.enabled=true时才会启用（默认为true）
 *
 * @author min
 */
@Configuration
@ConditionalOnProperty(prefix = "dtm", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(DistributedTransactionProperties.class)
@ComponentScan(basePackages = "cn.minhx.dtm.starter")
@EntityScan(basePackages = "cn.minhx.dtm.starter.core.model")
@EnableJpaRepositories(basePackages = "cn.minhx.dtm.starter.core.repository")
@EnableScheduling
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
public class DistributedTransactionConfiguration {

	private static final Logger log = LoggerFactory.getLogger(DistributedTransactionConfiguration.class);

	private final DistributedTransactionProperties properties;

	public DistributedTransactionConfiguration(DistributedTransactionProperties properties) {
		this.properties = properties;
		log.info("初始化分布式事务配置，启用状态: {}", properties.isEnabled());
	}

	/** 创建事务处理线程池 */
	@Bean
	public ThreadPoolExecutor transactionExecutor() {
		log.info("初始化分布式事务处理线程池");
		return new ThreadPoolExecutor(properties.getThreadPool().getCorePoolSize(),
				properties.getThreadPool().getMaxPoolSize(), properties.getThreadPool().getKeepAliveTime(),
				TimeUnit.SECONDS, new ArrayBlockingQueue<>(properties.getThreadPool().getQueueCapacity()),
				new NamedThreadFactory(properties.getThreadPool().getThreadNamePrefix()),
				new ThreadPoolExecutor.CallerRunsPolicy());
	}

	/** 注册分布式事务切面 */
	@Bean
	public DistributedTransactionAspect distributedTransactionAspect(TransactionService transactionService) {
		log.info("注册分布式事务切面 DistributedTransactionAspect");
		return new DistributedTransactionAspect(transactionService);
	}

	/** 注册事务重试任务 只有在dtm.retry.enabled=true时才会创建（默认为true） */
	@Bean
	@ConditionalOnProperty(prefix = "dtm.retry", name = "enabled", havingValue = "true", matchIfMissing = true)
	public TransactionRetryTask transactionRetryTask(TransactionService transactionService) {
		log.info("注册分布式事务重试任务，扫描间隔: {}ms, 批次大小: {}", properties.getRetry().getScanInterval(),
				properties.getRetry().getBatchSize());
		return new TransactionRetryTask(transactionService, properties);
	}
}
